package springx.uitils;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiIgnore
@NoArgsConstructor
public class Rest<T> implements Serializable {
    @ApiModelProperty(value = "状态码")
    private int status;
    @ApiModelProperty(value = "状态信息")
    private String msg;
    @ApiModelProperty(value = "返回的Json数据")
    private T data;


    private Rest(RestStatus status){
        changeHttpStatus(status);
    }
    private Rest(RestStatus status,String msg){
        changeHttpStatus(status);
        this.msg = msg;
    }
    private Rest(RestStatus status,T data){
        changeHttpStatus(status);
        this.data = data;
    }
    private Rest(RestStatus status,String msg,T data){
        changeHttpStatus(status);
        this.data =  data;
        this.msg = msg;
    }

    private void changeHttpStatus(RestStatus status) {
        try {
            //Response请求头获取配置
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            //设置返回的请求头
            response.setStatus(status.getCode());
            this.status  = status.getCode();
            this.msg = status.getDesc();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 200 GET/PUT请求返回
     */

    public static <T> Rest<T> SUCCESS() {
        return new Rest<>(RestStatus.SUCCESS);
    }

    public static <T> Rest<T> SUCCESS(String msg) {
        return new Rest<>(RestStatus.SUCCESS, msg);
    }

    public static <T> Rest<T> SUCCESS(T data) {
        return new Rest<>(RestStatus.SUCCESS, data);
    }

    public static <T> Rest<T> SUCCESS(String msg, T data) {
        return new Rest<>(RestStatus.SUCCESS, msg, data);
    }

    /**
     * 201 POST请求返回
     */

    public static <T> Rest<T> CREATED() {
        return new Rest<>(RestStatus.CREATED);
    }

    public static <T> Rest<T> CREATED(String msg) {
        return new Rest<>(RestStatus.CREATED, msg);
    }

    public static <T> Rest<T> CREATED(T data) {
        return new Rest<>(RestStatus.CREATED, data);
    }

    public static <T> Rest<T> CREATED(String msg, T data) {
        return new Rest<>(RestStatus.CREATED, msg, data);
    }

    /**
     * 202 暂时挂起的请求
     */

    public static <T> Rest<T> ACCEPTED() {
        return new Rest<>(RestStatus.ACCEPTED);
    }

    public static <T> Rest<T> ACCEPTED(String msg) {
        return new Rest<>(RestStatus.ACCEPTED, msg);
    }

    public static <T> Rest<T> ACCEPTED(T data) {
        return new Rest<>(RestStatus.ACCEPTED, data);
    }

    public static <T> Rest<T> ACCEPTED(String msg, T data) {
        return new Rest<>(RestStatus.ACCEPTED, msg, data);
    }

    /**
     * 204 DELETE请求返回
     */

    public static <T> Rest<T> NO_CONTENT() {
        return new Rest<>(RestStatus.NO_CONTENT);
    }

    public static <T> Rest<T> NO_CONTENT(String msg) {
        return new Rest<>(RestStatus.NO_CONTENT, msg);
    }

    public static <T> Rest<T> NO_CONTENT(T data) {
        return new Rest<>(RestStatus.NO_CONTENT, data);
    }

    public static <T> Rest<T> NO_CONTENT(String msg, T data) {
        return new Rest<>(RestStatus.NO_CONTENT, msg, data);
    }

    /**
     * 304 用于判断缓存是否过期
     */

    public static <T> Rest<T> NO_CHANGE() {
        return new Rest<>(RestStatus.NO_CHANGE);
    }

    public static <T> Rest<T> NO_CHANGE(String msg) {
        return new Rest<>(RestStatus.NO_CHANGE, msg);
    }

    public static <T> Rest<T> NO_CHANGE(T data) {
        return new Rest<>(RestStatus.NO_CHANGE, data);
    }

    public static <T> Rest<T> NO_CHANGE(String msg, T data) {
        return new Rest<>(RestStatus.NO_CHANGE, msg, data);
    }

    /**
     * 400 接口调用失败
     */

    public static <T> Rest<T> BAD_REQUEST() {
        return new Rest<>(RestStatus.BAD_REQUEST);
    }

    public static <T> Rest<T> BAD_REQUEST(String msg) {
        return new Rest<>(RestStatus.BAD_REQUEST, msg);
    }

    public static <T> Rest<T> BAD_REQUEST(T data) {
        return new Rest<>(RestStatus.BAD_REQUEST, data);
    }

    public static <T> Rest<T> BAD_REQUEST(String msg, T data) {
        return new Rest<>(RestStatus.BAD_REQUEST, msg, data);
    }

    /**
     * 401 无身份信息
     */

    public static <T> Rest<T> UNAUTHORIZED() {
        return new Rest<>(RestStatus.UNAUTHORIZED);
    }

    public static <T> Rest<T> UNAUTHORIZED(String msg) {
        return new Rest<>(RestStatus.UNAUTHORIZED, msg);
    }

    public static <T> Rest<T> UNAUTHORIZED(T data) {
        return new Rest<>(RestStatus.UNAUTHORIZED, data);
    }

    public static <T> Rest<T> UNAUTHORIZED(String msg, T data) {
        return new Rest<>(RestStatus.UNAUTHORIZED, msg, data);
    }

    /**
     * 403 有身份信息，但是无权限调用
     */

    public static <T> Rest<T> FORBIDDEN() {
        return new Rest<>(RestStatus.FORBIDDEN);
    }

    public static <T> Rest<T> FORBIDDEN(String msg) {
        return new Rest<>(RestStatus.FORBIDDEN, msg);
    }

    public static <T> Rest<T> FORBIDDEN(T data) {
        return new Rest<>(RestStatus.FORBIDDEN, data);
    }

    public static <T> Rest<T> FORBIDDEN(String msg, T data) {
        return new Rest<>(RestStatus.FORBIDDEN, msg, data);
    }

    /**
     * 404 资源不存在
     */

    public static <T> Rest<T> NOT_FOUND() {
        return new Rest<>(RestStatus.NOT_FOUND);
    }

    public static <T> Rest<T> NOT_FOUND(String msg) {
        return new Rest<>(RestStatus.NOT_FOUND, msg);
    }

    public static <T> Rest<T> NOT_FOUND(T data) {
        return new Rest<>(RestStatus.NOT_FOUND, data);
    }

    public static <T> Rest<T> NOT_FOUND(String msg, T data) {
        return new Rest<>(RestStatus.NOT_FOUND, msg, data);
    }

    /**
     * 410 请求已过时
     */

    public static <T> Rest<T> GONE() {
        return new Rest<>(RestStatus.GONE);
    }

    public static <T> Rest<T> GONE(String msg) {
        return new Rest<>(RestStatus.GONE, msg);
    }

    public static <T> Rest<T> GONE(T data) {
        return new Rest<>(RestStatus.GONE, data);
    }

    public static <T> Rest<T> GONE(String msg, T data) {
        return new Rest<>(RestStatus.GONE, msg, data);
    }

    /**
     * 429 请求次数过多
     */

    public static <T> Rest<T> TOO_MANY() {
        return new Rest<>(RestStatus.TOO_MANY);
    }

    public static <T> Rest<T> TOO_MANY(String msg) {
        return new Rest<>(RestStatus.TOO_MANY, msg);
    }

    public static <T> Rest<T> TOO_MANY(T data) {
        return new Rest<>(RestStatus.TOO_MANY, data);
    }

    public static <T> Rest<T> TOO_MANY(String msg, T data) {
        return new Rest<>(RestStatus.TOO_MANY, msg, data);
    }

    /**
     * 500 服务器错误
     */

    public static <T> Rest<T> ERROR() {
        return new Rest<>(RestStatus.ERROR);
    }

    public static <T> Rest<T> ERROR(String msg) {
        return new Rest<>(RestStatus.ERROR, msg);
    }

    public static <T> Rest<T> ERROR(T data) {
        return new Rest<>(RestStatus.ERROR, data);
    }

    public static <T> Rest<T> ERROR(String msg, T data) {
        return new Rest<>(RestStatus.ERROR, msg, data);
    }

    /**
     * 通用，请传入status
     */

    public static <T> Rest<T> COMMON(RestStatus status) {
        return new Rest<>(status);
    }

    public static <T> Rest<T> COMMON(RestStatus status, String msg) {
        return new Rest<>(status, msg);
    }

    public static <T> Rest<T> COMMON(RestStatus status, T data) {
        return new Rest<>(status, data);
    }

    public static <T> Rest<T> COMMON(RestStatus status, String msg, T data) {
        return new Rest<>(status, msg, data);
    }

    /**
     * 抛出异常
     */

    public static void Exception(String msg) throws RestException {
        throw new RestException(msg);
    }

    public static void Exception(RestStatus status) throws RestException {
        throw new RestException(status, status.getDesc());
    }

    public static void Exception(RestStatus status, String msg) throws RestException {
        throw new RestException(status, msg);
    }
}
